package com.yzkj.cpjxc.business.framework.utils.bean;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class BeanHelp {

	/**
	 * 比较两个同类型的对象有哪些属性值不同,特定的属性可以根据指定的规则进行比较
	 */
	public static List<String> compareDiffProps(Object bean1, Object bean2, Map<String, BeanCompareRule> propertyRuleMap) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		// 1、定义List
		List<String> list = new ArrayList<String>();
		
		// 2、获取对象里面有哪些属性
		Field[] fields = bean1.getClass().getDeclaredFields();

		// 3、把每个属性的名称放到一个字符串数组里
		String[] fieldNames = new String[fields.length];
		for (int i = 0; i < fields.length; i++) {
			fieldNames[i] = fields[i].getName();
			String propertyName = fields[i].getName();
			boolean flag = false;
			Object val1 = getPropertyValue(bean1, propertyName);
			Object val2 = getPropertyValue(bean2, propertyName);
			//System.out.println(val1 + "=====" + val2);
			
			// 4、 判断是否有传进来比对规则
			boolean hasRule = propertyRuleMap != null && propertyRuleMap.containsKey(propertyName); 
			// 4.1 有规则
			if (hasRule) {
				flag = propertyRuleMap.get(propertyName).compareEquals(val1, val2);
			} else {// 4.2 无规则
				if (val1 == null) {
					if (val2 == null) {
						flag = true;
					}
				} else {
					if (val1.equals(val2)) {
						flag = true;
					}
				}
			}
			
			if (!flag) {
				list.add(propertyName);
			}
		}
		return list;
	}

	/**
	 * 比较两个同类型的对象有哪些属性值不同
	 */
	public static List<String> compareDiffProps(Object bean1, Object bean2) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		return compareDiffProps(bean1, bean2, null);
	}
	
	/**
	 * 根据JavaBean属性名称获取属性值
	 */
	public static Object getPropertyValue(Object bean, String property) throws IllegalArgumentException, IllegalAccessException {
		// 1、获取bean里面的所有属性
		Field[] fields = bean.getClass().getDeclaredFields();

		// 2、根据传进来的属性名称，遍历bean里面的所有属性进行匹配，如果相同就获取值，并返回
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				if (property.equals(field.getName())) {
					field.setAccessible(true);
					return field.get(bean);
				}
			}
		}
		
		// 3、找不到就返回null
		return null;
	}

	/**
	 * 获取Bean对象的所有属性Map ===> Map<属性名, 属性类型>
	 */
	public static Map<String, Type> getBeanPropsMap(Object bean) {
		Map<String, Type> map = new LinkedHashMap<String, Type>();
		// 1、获取对象里面有哪些属性
		Field[] fields = bean.getClass().getDeclaredFields();
		// 2、把每个属性的名称放到一个字符串数组里
		String[] fieldNames = new String[fields.length];
		for (int i = 0; i < fields.length; i++) {
			fieldNames[i] = fields[i].getName();
			map.put(fields[i].getName(), fields[i].getType());
		}
		return map;
	}

}
